package com.sinai.mshab.widgets;

import java.util.ArrayList;

import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.FocusPanel;
import com.google.gwt.user.client.ui.HasVerticalAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.Widget;
import com.sinai.mshab.format.util.Observable;
import com.sinai.mshab.format.util.Observer;

/**
 * A menu item intended to be used in a {@link Menu}.
 * 
 * @author serge
 * 
 */
public class MenuButton extends FocusPanel implements Observable {

	/**
	 * Buttons can be selected, in which case they have different CSS.
	 */
	private boolean selected = false;

	private ArrayList<Observer> observers = new ArrayList<Observer>();

	/**
	 * Each button should have some text associated with it.
	 */
	private String text;

	private String notifyMessage;

	/**
	 * Creates a menu button intended to be used in a {@link Menu}
	 * 
	 * @param o the observer who to notify
	 * @param image the image to use in this button
	 * @param text the text to show up in this button
	 * @param notify_message the message to send to the observer when this button is clicked.
	 */
	public MenuButton(Observer o, String image, String text,
			String notify_message) {
		observers.add(o);
		notifyMessage = notify_message;
		addClickListener(new ButtonClickedListener());
		setUp(image, text);
	}

	/**
	 * Creates a menu button intended to be used in a {@link Menu}
	 * 
	 * @param o the observer who to notify
	 * @param text the text to show up in this button
	 * @param notify_message the message to send to the observer when this button is clicked.
	 */
	public MenuButton(Observer o, String text, String notify_message) {
		observers.add(o);
		notifyMessage = notify_message;
		addClickListener(new ButtonClickedListener());
		setUp(null, text);
	}

	private void setUp(String image, String text) {
		// remember the text.
		this.setText(text);

		// we need to catch mouse events.
		sinkEvents(Event.ONMOUSEOUT);
		sinkEvents(Event.ONMOUSEOVER);

		// set up this panel.
		setStyleName("mshab-MenuButton");
		// setVerticalAlignment(HasVerticalAlignment.ALIGN_MIDDLE);
		// setHorizontalAlignment(HasHorizontalAlignment.ALIGN_LEFT);

		// for layout reasons, we store icon and label in another panel.
		HorizontalPanel padding_panel = new HorizontalPanel();
		padding_panel.setStyleName("mshab-ButtonContents");
		padding_panel.setVerticalAlignment(HasVerticalAlignment.ALIGN_BOTTOM);

		// not all buttons need icons.
		if (image != null) {
			padding_panel.add(new Image(image));
		}
		padding_panel.add(new Label(text));
		add(padding_panel);
	}

	/**
	 * This method handles the CSS changes for mouse-overs. Selected buttons
	 * remain unaffected by mouse-overs.
	 */
	public void onBrowserEvent(Event event) {
		if (!selected && DOM.eventGetType(event) == Event.ONMOUSEOVER) {
			setStyleName("mshab-MenuButton-over");
		} else if (!selected && DOM.eventGetType(event) == Event.ONMOUSEOUT) {
			setStyleName("mshab-MenuButton");
		}
		super.onBrowserEvent(event);
	}

	/**
	 * Sets this button as selected.
	 * 
	 * @param selected
	 */
	public void setSelected(boolean selected) {
		this.selected = selected;
		if (selected) {
			setStyleName("mshab-MenuButton-selected");
		} else {
			setStyleName("mshab-MenuButton");
		}
	}

	public boolean isSelected() {
		return selected;
	}

	public void setText(String text) {
		this.text = text;
	}

	public String getText() {
		return text;
	}

	public void addObserver(Observer o) {
		observers.add(o);
	}

	public void notifyObservers() {
		for (int i = 0; i < observers.size(); i++) {
			observers.get(i).update(this, notifyMessage);
		}
	}

	public int countObservers() {
		return observers.size();
	}

	public void deleteObserver(Observer observer) {
		observers.remove(observer);
	}

	public void deleteObservers() {
		observers.clear();
	}
	private class ButtonClickedListener implements ClickListener {
		public void onClick(Widget sender) {
			notifyObservers();
		}
	}
}
